package org.lisy.java.io;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.InetAddress;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import com.alibaba.fastjson.util.IOUtils;

public class PingOperate {

	public static void main(String[] args) {
		String ipAddress = "127.0.0.1";
		System.out.println(pingNet(ipAddress));
		System.out.println(pingPro(ipAddress));
		System.out.println(pingPros(ipAddress, 1, 3000));
	}

	public static boolean pingNet(String ipAddress) {
		// 超时应该在3钞以上
		int timeOut = 3000;
		boolean status = false;
		try {
			status = InetAddress.getByName(ipAddress).isReachable(timeOut);
		} catch (IOException e) {
			e.printStackTrace();
		}
		// 当返回值是 true 时，说明 host 是可用的，false 则不可
		return status;
	}

	public static boolean pingPro(String ipAddress) {
		boolean result = false;
		String line = null;
		BufferedReader buf = null;
		try {
			Process pro = Runtime.getRuntime().exec("ping " + ipAddress);
			buf = new BufferedReader(new InputStreamReader(pro.getInputStream()));
			while ((line = buf.readLine()) != null) {
				if(line.contains("TTL")) {
					result= true;
					break;
				}
			}
		} catch (Exception ex) {
			System.out.println(ex.getMessage());
		} finally {
			IOUtils.close(buf);
		}
		return result;
	}

	public static boolean pingPros(String ipAddress, int pingTimes, int timeOut) {
		BufferedReader in = null;
		// 将要执行的 ping 命令, 此命令是 windows 格式的命令
		Runtime r = Runtime.getRuntime();
		String pingCommand = "ping " + ipAddress + " -n " + pingTimes + " -w " + timeOut;
		try {
			// 执行命令并获取输出
			Process p = r.exec(pingCommand);
			if (p == null) {
				return false;
			}
			in = new BufferedReader(new InputStreamReader(p.getInputStream()));
			int connectedCount = 0;
			String line = null;
			// 逐行检查输出,计算类似出现=23ms TTL=62字样的次数
			while ((line = in.readLine()) != null) {
				connectedCount += getCheckResult(line);
			}
			// 判断次数
			return connectedCount == pingTimes;
		} catch (Exception ex) {
			ex.printStackTrace(); 
			return false;
		} finally {
			IOUtils.close(in);
		}
	}

	private static int getCheckResult(String line) {
		// 若 line 含有=18ms TTL=16 字样,说明已经 ping 通, 返回 1, 否則返回 0
		Pattern pattern = Pattern.compile("(\\d+ms)(\\s+)(TTL=\\d+)", Pattern.CASE_INSENSITIVE);
		Matcher matcher = pattern.matcher(line);
		while (matcher.find()) {
			return 1;
		}
		return 0;
	}
}
